<html>
 <head>
  <meta charset="UTF-8">
 </head>
 <body>
  <h1 data-lake-id="BeLjC" id="BeLjC"><span data-lake-id="u0e94f6df" id="u0e94f6df">典型回答</span></h1>
  <p data-lake-id="u688fc49e" id="u688fc49e"><br></p>
  <p data-lake-id="ub13b35f6" id="ub13b35f6"><span data-lake-id="uae1250a0" id="uae1250a0">MySQL的组提交（Group Commit）是一项优化技术，用于提高数据库系统的性能和事务处理的效率。它通过将多个事务的提交操作合并成一个批处理操作来减少磁盘IO和锁定开销，从而加速事务的处理。</span></p>
  <p data-lake-id="u7bff6d93" id="u7bff6d93"><span data-lake-id="u1a0c0578" id="u1a0c0578">​</span><br></p>
  <p data-lake-id="u531ea2a6" id="u531ea2a6"><span data-lake-id="ua50d5ffd" id="ua50d5ffd">我们的数据库需要不断地执行很多次数据变更，并且每次变更都需要把数据持久化下来，以方便进行崩溃恢复及主从同步、还有回滚等，这就涉及到binlog、redolog以及undolog的写入。</span></p>
  <p data-lake-id="u779746c2" id="u779746c2"><span data-lake-id="u337cdafb" id="u337cdafb">​</span><br></p>
  <p data-lake-id="u143461bb" id="u143461bb"><span data-lake-id="ue293797c" id="ue293797c">而频繁的文件写入需要会触发频繁磁盘写入操作，为了减少提交操作的开销，MySQL引入了组提交技术，就是</span><strong><span data-lake-id="u244fdce8" id="u244fdce8">将多个事务的提交操作可以合并成一个批处理操作，以减少磁盘IO次数。</span></strong><span data-lake-id="u842d1377" id="u842d1377">这个批处理操作将包含多个事务的修改，并一次性写入二进制日志。</span></p>
  <p data-lake-id="uf2505fa0" id="uf2505fa0"><span data-lake-id="uffb45d0f" id="uffb45d0f">​</span><br></p>
  <p data-lake-id="ub29e2af9" id="ub29e2af9"><span data-lake-id="u817bb8f5" id="u817bb8f5">通过以下命令可以查看关于组提交的配置：</span></p>
  <p data-lake-id="uff660526" id="uff660526"><span data-lake-id="u1185789c" id="u1185789c">​</span><br></p>
  <pre lang="java"><code>
mysql&gt; show variables like '%group_commit%';                                                                                                                                         
+-----------------------------------------+-------+                                                                                                                                  
| Variable_name                           | Value |                                                                                                                                  
+-----------------------------------------+-------+                                                                                                                                  
| binlog_group_commit_sync_delay          | 0     |                                                                                                                                  
| binlog_group_commit_sync_no_delay_count | 0     |                                                                                                                                  
+-----------------------------------------+-------+                                                                                                                                  
2 rows in set (0.00 sec) 
</code></pre>
  <p data-lake-id="u85d4b4db" id="u85d4b4db"><br></p>
  <ul list="uebf7731b">
   <li fid="u8b95c303" data-lake-id="u1883e202" id="u1883e202"><span data-lake-id="u437ea5b7" id="u437ea5b7">binlog_group_commit_sync_delay</span></li>
  </ul>
  <ul list="uebf7731b" data-lake-indent="1">
   <li fid="u8b95c303" data-lake-id="u58a14229" id="u58a14229"><span data-lake-id="u5956a9ca" id="u5956a9ca">延迟多长时间再通过fsync进行刷盘，把数据持久化</span></li>
  </ul>
  <ul list="uebf7731b" start="2">
   <li fid="u8b95c303" data-lake-id="u22d50715" id="u22d50715"><span data-lake-id="u3990503a" id="u3990503a">binlog_group_commit_sync_no_delay_count</span></li>
  </ul>
  <ul list="uebf7731b" data-lake-indent="1">
   <li fid="u8b95c303" data-lake-id="u37104b5d" id="u37104b5d"><span data-lake-id="u8887f40d" id="u8887f40d">累积多少次操作再通过fsync进行刷盘，把数据持久化</span></li>
  </ul>
  <p data-lake-id="uf2a18697" id="uf2a18697"><span data-lake-id="u0e39bdb1" id="u0e39bdb1">​</span><br></p>
  <p data-lake-id="ubb6e210d" id="ubb6e210d"><span data-lake-id="u34611988" id="u34611988">注意，这两个条件是或的关系，只要满足一个，就会触发提交动作。</span></p>
  <p data-lake-id="u39101a71" id="u39101a71"><span data-lake-id="u5ca7be01" id="u5ca7be01">​</span><br></p>
  <p data-lake-id="ub11aea08" id="ub11aea08"><span data-lake-id="ub39861f0" id="ub39861f0">​</span><br></p>
  <h1 data-lake-id="RZ5Eq" id="RZ5Eq"><span data-lake-id="u8a27ad7e" id="u8a27ad7e">扩展知识</span></h1>
  <p data-lake-id="u2878f7af" id="u2878f7af"><br></p>
  <h2 data-lake-id="bVZOT" id="bVZOT"><span data-lake-id="ud47efca6" id="ud47efca6">有了组提交后的2阶段</span></h2>
  <p data-lake-id="u8d733273" id="u8d733273"><br></p>
  <p data-lake-id="u349eeb94" id="u349eeb94"><span data-lake-id="u3d7d0f18" id="u3d7d0f18">​</span><br></p>
  <p data-lake-id="u871ffeea" id="u871ffeea"><span data-lake-id="u0985c5d3" id="u0985c5d3">在有了组提交之后，2阶段就会有一些变化，因为日志的刷盘过程会因为组提交而需要等待，所以会变成这样：</span></p>
  <p data-lake-id="u2678d611" id="u2678d611"><span data-lake-id="u8f45c31a" id="u8f45c31a">​</span><br></p>
  <p data-lake-id="ue1f9bee8" id="ue1f9bee8"><img src="https://cdn.nlark.com/yuque/0/2023/png/5378072/1692967827189-6aab9276-25ee-4d75-8dea-0506e886387e.png?x-oss-process=image%2Fwatermark%2Ctype_d3F5LW1pY3JvaGVp%2Csize_23%2Ctext_SmF2YSA4IEd1IFA%3D%2Ccolor_FFFFFF%2Cshadow_50%2Ct_80%2Cg_se%2Cx_10%2Cy_10"></p>
  <p data-lake-id="ub397e8c1" id="ub397e8c1"><br></p>
  <p data-lake-id="u1cd1b616" id="u1cd1b616"><span data-lake-id="u0bbfb3ab" id="u0bbfb3ab">这里面write 和 fsync 是与文件系统和磁盘IO相关的两个不同的操作。</span></p>
  <p data-lake-id="u79b0c7a8" id="u79b0c7a8"><span data-lake-id="u6c8a24e5" id="u6c8a24e5">​</span><br></p>
  <p data-lake-id="u535fad45" id="u535fad45"><span data-lake-id="u19c7f2e7" id="u19c7f2e7">write 操作将数据写入文件的缓冲区，这意味着 write 操作完成后，并不一定立即将数据持久化到磁盘上，而是将数据暂时存储在内存中。</span></p>
  <p data-lake-id="u44961cbf" id="u44961cbf"><span data-lake-id="u7586774f" id="u7586774f">​</span><br></p>
  <p data-lake-id="u33ea8bdd" id="u33ea8bdd"><span data-lake-id="uee1df794" id="uee1df794">fsync 用于强制将文件的修改持久化到磁盘上。它通常与 write 配合使用，以确保文件的修改在 fsync 操作完成后被写入磁盘。</span></p>
  <p data-lake-id="u5ad5b17e" id="u5ad5b17e"><br></p>
  <p data-lake-id="ucc97e886" id="ucc97e886"><span data-lake-id="u1e4879d7" id="u1e4879d7">所以，用于将缓冲区内容持久化到磁盘的fsync这一步，被延迟了。他会等一个组中多个事务都处于Prepare阶段后，然后进行一次组提交，即把日志持久化到磁盘中。</span></p>
 </body>
</html>